﻿using System.Linq.PageList;
using Dyao.Book.Application.Abstractions;
using Dyao.Book.Contract;
using Dyao.Book.Entity;
using Dyao.Book.Repository.Abstractions;
using Foundation.Core;
using Foundation.Uow;
using Dyao.Book.Core;

namespace Dyao.Book.Application
{
    public class ChapterMgrApplication : BaseApplication, IChapterMgrApplication
    {
        private readonly IChapterMgrRepository _chapterMgrRepository;

        private readonly IBookCatalogueRepository _bookCatalogueRepository;

        public ChapterMgrApplication(IChapterMgrRepository chapterMgrRepository,
            IBookCatalogueRepository bookCatalogueRepository)
        {
            _chapterMgrRepository = chapterMgrRepository;
            _bookCatalogueRepository = bookCatalogueRepository;
        }

        /// <inheritdoc cref="IChapterMgrApplication.GetPageListAsync"/>
        public async Task<IPageList<ChapterResultDto>> GetPageListAsync(IPageFilter<ChapterFilterDto> pageFilter, CancellationToken cancellationToken = default)
        {
            var result = new PageList<ChapterResultDto>();
            using var unitOfWork = UnitOfWorkManager.Begin(isReadDb: true);

            var pageList = await _chapterMgrRepository.GetPageListAsync(pageFilter, cancellationToken);

            if (pageList.Records == 0) return result;

            var resultList = ObjectMapper.Map<List<BookCatalogueEntity>, List<ChapterResultDto>>(pageList.Data);

            return (PageList<ChapterResultDto>)pageList.ToMap(resultList);
        }

        /// <inheritdoc cref="IChapterMgrApplication.ModifyAsync"/>
        public async Task<string> ModifyAsync(ChapterInfoDto chapterInfo, CancellationToken cancellationToken = default)
        {
            if (chapterInfo.Id.IsNullOrEmpty())
                throw new BusinessException("ChapterMgr_Modify_Id", "章节编号不能为空");

            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var entity = await _bookCatalogueRepository.GetByIdAsync(chapterInfo.Id, cancellationToken);
                if (entity == null)
                    throw new BusinessException("ChapterMgr_Modify_BookIsNull", "章节信息不存在");

                entity.CatalogueName = chapterInfo.ChapterName;
                entity.Keyword = chapterInfo.Keyword;
                entity.ContentLink = chapterInfo.ContentLink;
                entity.SourceKey = chapterInfo.SourceKey;
                entity.UpdateUserId = CurrentUser.GetUserId().ToInt();
                entity.UpdateUserName = CurrentUser.UserName;
                entity.UpdateDateTime = DateTime.Now;

                await unitOfWork.SaveChangesAsync(cancellationToken);
                await unitOfWork.CompleteAsync(cancellationToken);
            }

            return "修改成功";
        }

        /// <inheritdoc cref="IChapterMgrApplication.DeleteAsync"/>
        public async Task<string> DeleteAsync(string chapterId, CancellationToken cancellationToken = default)
        {
            if (chapterId.IsNullOrEmpty())
                throw new BusinessException("ChapterMgr_Delete_Id", "章节编号不能为空");

            var ids = chapterId.SplitDefaultToList(); // 章节编号
            var contentRepository = GetService<IBookCatalogueContentRepository>();

            using (var unitOfWork = UnitOfWorkManager.Begin(isTransactional: true))
            {
                var entities = await _bookCatalogueRepository.GetListByIdsAsync(ids, b => new BookCatalogueEntity { ID = b.ID }, cancellationToken);
                if (entities.IsNullOrEmpty())
                    throw new BusinessException("ChapterMgr_Delete_BookIsNull", "章节信息不存在");

                // 删除内容
                var contentEntites = entities.Select(e => new BookCatalogueContentEntity()
                {
                    BookCatalogueId = e.ID,
                });

                await _bookCatalogueRepository.BulkDeleteAsync(entities, cancellationToken);
                await contentRepository.BulkDeleteAsync(contentEntites, bc => new { bc.BookCatalogueId }, cancellationToken);
                await unitOfWork.SaveChangesAsync(cancellationToken);
                await unitOfWork.CompleteAsync(cancellationToken);
            }
            return "删除成功";
        }
    }
}
